package cn.stylefeng.guns.sys.modular.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.stylefeng.guns.base.pojo.page.LayuiPageFactory;
import cn.stylefeng.guns.base.pojo.page.LayuiPageInfo;
import cn.stylefeng.guns.sys.core.constant.cache.CacheKey;
import cn.stylefeng.guns.sys.core.properties.TcConfig;
import cn.stylefeng.guns.sys.core.util.DateUtil;
import cn.stylefeng.guns.sys.core.util.RedisUtils;
import cn.stylefeng.guns.sys.modular.system.entity.BtyInventory;
import cn.stylefeng.guns.sys.modular.system.entity.DsstoreBill;
import cn.stylefeng.guns.sys.modular.system.mapper.DsstoreBillMapper;
import cn.stylefeng.guns.sys.modular.system.model.params.DsstoreBillParam;
import cn.stylefeng.guns.sys.modular.system.model.params.ItemBusUnitParam;
import cn.stylefeng.guns.sys.modular.system.model.result.DsstoreBillBusType;
import cn.stylefeng.guns.sys.modular.system.model.result.DsstoreBillResult;
import cn.stylefeng.guns.sys.modular.system.service.DsstoreBillService;
import cn.stylefeng.guns.sys.modular.system.service.ItemInterfaceService;
import cn.stylefeng.roses.core.reqres.response.ResponseData;
import cn.stylefeng.roses.core.util.ToolUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.io.Serializable;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author jiangge
 * @since 2020-09-15
 */
@Service
public class DsstoreBillServiceImpl extends ServiceImpl<DsstoreBillMapper, DsstoreBill> implements DsstoreBillService {
    private Logger logger = LoggerFactory.getLogger(DsstoreBillServiceImpl.class);
    private RestTemplate restTemplate = new RestTemplate();
    @Resource
    private RedisUtils redisUtils;
    @Autowired
    private ItemInterfaceService itemInterfaceService;
    @Autowired
    private TcConfig tcConfig;

    @Override
    public void add(DsstoreBillParam param) {
        DsstoreBill entity = getEntity(param);
        this.save(entity);
    }

    @Override
    public void delete(DsstoreBillParam param) {
        this.removeById(getKey(param));
    }

    @Override
    public void update(DsstoreBillParam param) {
        DsstoreBill oldEntity = getOldEntity(param);
        DsstoreBill newEntity = getEntity(param);
        ToolUtil.copyProperties(newEntity, oldEntity);
        this.updateById(newEntity);
    }

    @Override
    public DsstoreBillResult findBySpec(DsstoreBillParam param) {
        return null;
    }

    @Override
    public List<DsstoreBillResult> findListBySpec(DsstoreBillParam param) {
        return null;
    }

    @Override
    public LayuiPageInfo findPageBySpec(DsstoreBillParam param) {
        Page pageContext = getPageContext();
        IPage page = this.baseMapper.customPageList(pageContext, param);
        return LayuiPageFactory.createPageInfo(page);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Integer> initDsstorebillData(List<String> dateList) {
        List<String> dateParamList = new ArrayList<>();
        //业务日期
        dateParamList.add("busdate");
        //审核日期-1.业务日期数据 2.修改的数据 3.之前的数据插入
        dateParamList.add("auditDate");

        //某月底可能无法走接口录入数据，此时需要先执行删除语句，然后将业务json数据录入、审核日期对应json数据录入
        for (String dateParam : dateParamList) {
            for (String day : dateList) {
                //业务日期当天的数据先删除掉，改单删单可能存在垃圾数据
                if (dateParam.equals("busdate")) {
                    this.baseMapper.deleteDataByDay(day);
                }
                if (dateParam.equals("auditDate")) {
                    this.baseMapper.deleteDataByDay2(day);
                }
            }
        }

        //数据条数
        Map<String, Integer> map = new LinkedHashMap<>();
        Map<String, DsstoreBill> listMap = new HashMap<>();

        for (String dateParam : dateParamList) {

            for (String day : dateList) {

                Long startTime = System.currentTimeMillis();
                String url = "http://btyjt.c3.fxscm.net/cldpoint/getDsstorebill.do?ent=ENT7617&username="+tcConfig.getUsername()+"&password="+tcConfig.getPassword()+"&" + dateParam + "=" + day;
                String content = restTemplate.getForObject(url, String.class);
                Long respondTime = (System.currentTimeMillis() - startTime) / 1000;

                JSONObject jsonObjectResult = JSON.parseObject(content);
                JSONArray jsonArray = jsonObjectResult.getJSONArray("data");

                /**
                 * ShopCode    ShopName	ItemSmallClassName  ItemName
                 * 没有店名查询的的是所有的店,把获取到的数据取出来便利 然后挨个插入到表中
                 */
                JSONObject jsonObject;
                Integer allDataCount = jsonArray.size();
                List<DsstoreBill> thisDayData = Lists.newLinkedList();

                for (int i = 0; i < jsonArray.size(); i++) {
                    //把所有 ItemSmallClassName 为 酱料 的添加到list中
                    jsonObject = jsonArray.getJSONObject(i);
                    List<String> type1 = Lists.newLinkedList();
                    type1.add("门店统配入库");
                    type1.add("门店直配入库");
                    type1.add("门店自采入库");
                    type1.add("门店其他入库");
                    type1.add("门店期初单");
                    type1.add("店间调入");
                    type1.add("门店盘盈");
                    type1.add("门店盘亏");
                    type1.add("门店外销退货");
                    type1.add("门店冲减出库");
                    type1.add("门店报损出库");
                    type1.add("门店外销出库");
                    type1.add("门店统配退货单");
                    type1.add("门店部门领用");
                    type1.add("店内档口领用");
                    type1.add("店间调出");
                    type1.add("门店其他出库");
                    type1.add("门店自采退货");


                    if ("酱料".equals(jsonObject.getOrDefault("ItemSmallClassName", "").toString())
                            && type1.contains(jsonObject.getOrDefault("BillType", ""))
                            && !"山西配送中心".equals(jsonObject.getOrDefault("ShopName", "").toString())
                            && !"山东配送中心".equals(jsonObject.getOrDefault("ShopName", "").toString())) {
                        DsstoreBill dsstoreBill = convertToDsstoreBill(jsonObject);
                        DsstoreBillBusType dsstoreBillBusType2 = new DsstoreBillBusType();
                        dsstoreBillBusType2.setBillBusType(dsstoreBill.getBillBusType());
                        dsstoreBillBusType2.setBillType(dsstoreBill.getBillType());
//                        if (dsstoreBill.getShopCode().equals("039")) {
                        listMap.put(dsstoreBill.getStoreBillDtid(), dsstoreBill);
//                        }
                        thisDayData.add(dsstoreBill);
                    }
                }
                logger.info("门店库存流水入库数据：{},数据时间：{},数据总数：{}，满足条件：{}条数据,请求响应时间：{}", dateParam, day, allDataCount, thisDayData.size(), respondTime);
                map.put(day + dateParam, thisDayData.size());
            }
        }

        //分批插入数据
        if (listMap.size() > 0) {
            int currentComplete = 0;
            for (Map.Entry<String, DsstoreBill> dsstoreBillEntry : listMap.entrySet()) {
                DsstoreBill dsstoreBill = dsstoreBillEntry.getValue();
                currentComplete++;
                try {
                    this.saveOrUpdate(dsstoreBill);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        }

        //删除不在数据范围内的数据
        return map;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteDsstorebillDataByDays(List<String> dateList) {

        List<String> dateParamList = new ArrayList<>();
        //业务日期
        dateParamList.add("busdate");

        for (String dateParam : dateParamList) {
            for (String day : dateList) {
                //因为存在删单现象，每次保存后将当天不该存在的数据删除
                Map<String, List<String>> sureHaveDataMap = new HashMap<>();

                String url = "http://btyjt.c3.fxscm.net/cldpoint/getDsstorebill.do?ent=ENT7617&username="+tcConfig.getUsername()+"&password="+tcConfig.getPassword()+"&" + dateParam + "=" + day;
                String content = restTemplate.getForObject(url, String.class);

                JSONObject jsonObjectResult = JSON.parseObject(content);
                JSONArray jsonArray = jsonObjectResult.getJSONArray("data");

                /**
                 * ShopCode    ShopName	ItemSmallClassName  ItemName
                 * 没有店名查询的的是所有的店,把获取到的数据取出来便利 然后挨个插入到表中
                 */
                JSONObject jsonObject;

                for (int i = 0; i < jsonArray.size(); i++) {
                    //把所有 ItemSmallClassName 为 酱料 的添加到list中
                    jsonObject = jsonArray.getJSONObject(i);
                    List<String> type1 = Lists.newLinkedList();
                    type1.add("门店统配入库");
                    type1.add("门店直配入库");
                    type1.add("门店自采入库");
                    type1.add("门店其他入库");
                    type1.add("门店期初单");
                    type1.add("店间调入");
                    type1.add("门店盘盈");
                    type1.add("门店盘亏");
                    type1.add("门店外销退货");
                    type1.add("门店冲减出库");
                    type1.add("门店报损出库");
                    type1.add("门店外销出库");
                    type1.add("门店统配退货单");
                    type1.add("门店部门领用");
                    type1.add("店内档口领用");
                    type1.add("店间调出");
                    type1.add("门店其他出库");
                    type1.add("门店自采退货");

                    DsstoreBillBusType dsstoreBillBusType = new DsstoreBillBusType();
                    dsstoreBillBusType.setBillBusType(jsonObject.getOrDefault("BillBusType", "").toString());
                    dsstoreBillBusType.setBillType(jsonObject.getOrDefault("BillType", "").toString());

                    if ("酱料".equals(jsonObject.getOrDefault("ItemSmallClassName", "").toString())
                            && type1.contains(jsonObject.getOrDefault("BillType", ""))
                            && !"山西配送中心".equals(jsonObject.getOrDefault("ShopName", "").toString())
                            && !"山东配送中心".equals(jsonObject.getOrDefault("ShopName", "").toString())) {
                        DsstoreBill dsstoreBill = convertToDsstoreBill(jsonObject);
                        //删除不在业务日期当天的数据
                        if (dateParam.equals("busdate")) {
                            List<String> idList = sureHaveDataMap.get(day);
                            if (idList != null) {
                                idList.add(dsstoreBill.getStoreBillDtid());
                                sureHaveDataMap.put(day, idList);
                            } else {
                                List<String> ids = new ArrayList<>();
                                ids.add(dsstoreBill.getStoreBillDtid());
                                sureHaveDataMap.put(day, ids);
                            }
                        }
                    }
                }
                this.deleteDataByDayAndIds(sureHaveDataMap);
            }
        }
    }

    @Override
    public void deleteDsstorebillDataByDelInterface(List<String> dateList) {

        //因为存在删单现象，每次保存后将当天不该存在的数据删除

        String url = "http://btyjt.c3.fxscm.net/cldpoint/getDeleteBillList.do?ent=ENT7617&username="+tcConfig.getUsername()+"&password="+tcConfig.getPassword()+"&beginDate=" + dateList.get(0) + "&endDate=" + dateList.get(dateList.size() - 1);
        String content = restTemplate.getForObject(url, String.class);

        JSONObject jsonObjectResult = JSON.parseObject(content);
        JSONArray jsonArray = jsonObjectResult.getJSONArray("data");

        /**
         * ShopCode    ShopName	ItemSmallClassName  ItemName
         * 没有店名查询的的是所有的店,把获取到的数据取出来便利 然后挨个插入到表中
         */
        JSONObject jsonObject;

        List<String> delIds = new ArrayList<>();
        for (int i = 0; i < jsonArray.size(); i++) {
            //把所有 ItemSmallClassName 为 酱料 的添加到list中
            jsonObject = jsonArray.getJSONObject(i);

            String storeBillId = jsonObject.get("storeBillId").toString();
            //删除数据
            delIds.add(storeBillId);
        }

        if (CollectionUtil.isNotEmpty(delIds)) {
            if (delIds.size() > 1000) {
                List<List<String>> partitionIdss = Lists.partition(delIds, 1000);
                for (List<String> list : partitionIdss) {
                    this.baseMapper.deleteBatchIds(list);
                }
            } else {
                this.baseMapper.deleteBatchIds(delIds);
            }
        }

    }

    @Transactional(rollbackFor = Exception.class)
    void deleteDataByDayAndIds(Map<String, List<String>> sureHaveDataMap) {
        //删除不在数据范围内的数据
        if (CollectionUtil.isNotEmpty(sureHaveDataMap)) {
            for (Map.Entry<String, List<String>> entry : sureHaveDataMap.entrySet()) {
                //应该存在的
                List<String> partitionIds = entry.getValue();
                //已经存在的
                List<String> allIds = this.baseMapper.selectIdsByDay(entry.getKey());
                //要删除的
                List<String> Idslist = getTwoListDifference(allIds, partitionIds);
                if (CollectionUtil.isNotEmpty(Idslist)) {
                    if (Idslist.size() > 1000) {
                        List<List<String>> partitionIdss = Lists.partition(Idslist, 1000);
                        for (List<String> list : partitionIdss) {
                            this.baseMapper.deleteDataByIds(list);
                        }
                    } else {
                        this.baseMapper.deleteDataByIds(Idslist);
                    }
                }
            }
        }
    }

    public List<String> getTwoListDifference(List<String> totalList, List<String> containsList) {
        HashMap<String, Boolean> map = new HashMap(0);
        for (int i = 0; i < containsList.size(); i++) {
            map.put(containsList.get(i), true);
        }
        containsList.clear();
        for (int i = 0; i < totalList.size(); i++) {
            if (!map.containsKey(totalList.get(i))) {
                containsList.add(totalList.get(i));
            }
        }
        return containsList;
    }


    /**
     * 获取转为商务单位为的数据
     *
     * @param param
     * @return
     */
    @Override
    public LayuiPageInfo getConutDataResult(DsstoreBillParam param) {
        //获取有门店初期单的数据
        DsstoreBillParam billParam = new DsstoreBillParam();
        billParam.setStartTime(param.getStartTime());
        List<DsstoreBillResult> results = this.baseMapper.selectBillsByBusTypeAndDate(billParam);
        Map<String, String> codeMap = new HashMap<>();
        if (CollectionUtil.isNotEmpty(results)) {
            codeMap = results.stream().collect(Collectors.toMap(DsstoreBillResult::getCodes, DsstoreBillResult::getShopCode));
        }


        Page pageContext = getPageContext();
        IPage page = this.baseMapper.getConutData(pageContext, param);
        //获取汇总数据
        //List<DsstoreBill> conutDataList = this.baseMapper.getConutData(param);
        List<DsstoreBillResult> conutDataList = page.getRecords();
        if (CollectionUtil.isNotEmpty(conutDataList)) {
            //获取所有品项的商务单位
            List<ItemBusUnitParam> allItemBusUnitList = itemInterfaceService.getAllItemBusUnit();
            Map<String, ItemBusUnitParam> unitMap = new HashMap<>();
            for (ItemBusUnitParam itemBusUnitParam : allItemBusUnitList) {
                unitMap.put(itemBusUnitParam.getItemCode(), itemBusUnitParam);
            }
            //换单位
            for (DsstoreBillResult dsstoreBill : conutDataList) {
                //没有门店初期单的，手动计算门店初期单
                if (codeMap.get(getItemCodes(dsstoreBill)) == null) {
                    logger.info("没有门店期初单，{}，{}", param.getStartTime(), getItemCodes(dsstoreBill));
                    //获取有初期单的最近的一个
                    Map<Object, Object> hmget = redisUtils.hmget(CacheKey.KC_CHUQIDAN_DATA);
                    if (CollectionUtil.isNotEmpty(hmget)) {
                        Map<String, String> busdateSets = (Map<String, String>) hmget.get(dsstoreBill.getShopCode());
                        //从最近的一个初期单日期计算库存
                        if (CollectionUtil.isNotEmpty(busdateSets)) {
                            //获得最近有门店期初单的日期
                            String recentMonthDay = getRecentChuQiDanMonthDay(dsstoreBill, busdateSets, param.getStartTime(), 0);
                            //从获得的最近有门店期初单的日期开始计算库存
                            DsstoreBillParam dsstoreBillParam = new DsstoreBillParam();
                            dsstoreBillParam.setShopCode(dsstoreBill.getShopCode());
                            dsstoreBillParam.setItemTypeCode(param.getItemTypeCode());
                            dsstoreBillParam.setItemCode(dsstoreBill.getItemCode());
                            dsstoreBillParam.setStartTime(recentMonthDay);
                            dsstoreBillParam.setEndTime(param.getEndTime());
                            DsstoreBillResult conutDataByParam = this.baseMapper.getConutDataByParam(dsstoreBillParam);
                            //将库存值写入
                            if (conutDataByParam != null) {
                                dsstoreBill.setItemBalanceAmout(conutDataByParam.getItemBalanceAmout());
                            }
                        }
                    }
                }
                BigDecimal itemBalanceAmount = dsstoreBill.getItemBalanceAmout();
                //对应的商务单位数据
                ItemBusUnitParam item = unitMap.get(dsstoreBill.getItemCode());
                //单位
                dsstoreBill.setItemBusUnit(item.getItemUnitName());
                //换算
                BigDecimal itemBalanceBusAmout = BigDecimal.ZERO;
                if (itemBalanceAmount != null && itemBalanceAmount.compareTo(BigDecimal.ZERO) != 0) {
                    itemBalanceBusAmout = itemBalanceAmount.divide(item.getUnitRatio(), 6, BigDecimal.ROUND_UP);
                }
                dsstoreBill.setItemBalanceBusAmout(itemBalanceBusAmout);
            }
        }
        return LayuiPageFactory.createPageInfo(page);
    }

    @Override
    public DsstoreBillResult selectRkAndTotalRkje(BtyInventory params) {
        DsstoreBillResult dsstoreBillResult = this.baseMapper.selectRkAndTotalRkje(params);
        //获取所有品项的商务单位
        List<ItemBusUnitParam> allItemBusUnitList = itemInterfaceService.getAllItemBusUnit();
        Map<String, ItemBusUnitParam> unitMap = new HashMap<>();
        for (ItemBusUnitParam itemBusUnitParam : allItemBusUnitList) {
            unitMap.put(itemBusUnitParam.getItemCode(), itemBusUnitParam);
        }
        //商务单位 入库量
        BigDecimal inMainAmount = dsstoreBillResult.getInMainAmount();
        //对应的商务单位数据
        ItemBusUnitParam item = unitMap.get(dsstoreBillResult.getItemCode());
        //换算为箱
        BigDecimal itemBalanceBusAmout = inMainAmount.divide(item.getUnitRatio(), 6, BigDecimal.ROUND_HALF_UP);
        //单价=入库金额/入库数量,即一箱多少钱
        BigDecimal unitPrice = dsstoreBillResult.getInStoreMoney().divide(itemBalanceBusAmout, 4, BigDecimal.ROUND_HALF_UP);
        dsstoreBillResult.setUnitPrice(unitPrice);
        return dsstoreBillResult;
    }

    @Override
    public ResponseData initDsstorebillChuQiDanData() {
        //所有有初期单的数据，001_101_1000004_2019-12-01，shopCode_item_small_class_code_item_code_bus_date,门店编码_品类_品项_业务日期
        List<DsstoreBillResult> results = this.baseMapper.selectChuQiDanBillsByBusTypeAndDate();
        Map<String, List<DsstoreBillResult>> bxdaMap = results.stream().collect(Collectors.groupingBy(DsstoreBillResult::getShopCode));
        Map<String, Object> chuqidanMap = new HashMap<>();
        for (Map.Entry<String, List<DsstoreBillResult>> entry : bxdaMap.entrySet()) {
            String shopCode = entry.getKey();
            List<DsstoreBillResult> billList = entry.getValue();
            Map<String, String> codesSet = new HashMap<>();
            if (CollectionUtil.isNotEmpty(billList)) {
                for (DsstoreBillResult result : billList) {
                    codesSet.put(result.getCodes(), DateUtil.getStrDate(result.getBusDate()));
                }
                chuqidanMap.put(shopCode, codesSet);
            }
        }
        //放入缓存
        redisUtils.hmset(CacheKey.KC_CHUQIDAN_DATA, chuqidanMap);


        return ResponseData.success();
    }

    @Override
    public Map<String, Integer> initDsstorebillPurchaseData(List<String> dateList) {


        //数据条数
        Map<String, Integer> map = new LinkedHashMap<>();
        List<DsstoreBill> list = Lists.newLinkedList();

        Set<DsstoreBillBusType> billTypeSet1 = new HashSet();
        Set<DsstoreBillBusType> billTypeSet2 = new HashSet();

        //获取所有已经保存的值-store_bill_dtid不会重复
        List<DsstoreBillResult> dsstoreBillResults = this.baseMapper.getDsstoreBillList(new DsstoreBillParam());
        Map<String, String> dtMap = dsstoreBillResults.stream().collect(Collectors.toMap(DsstoreBillResult::getStoreBillDtid, DsstoreBillResult::getShopCode));

        List<String> dateParamList = new ArrayList<>();

        Map<String, Map<String, DsstoreBill>> shopDayPurchaseMap = new HashMap<>();

        //业务日期
        dateParamList.add("busdate");
        //审核日期-1.业务日期数据 2.修改的数据 3.之前的数据插入
        dateParamList.add("auditDate");
        for (String dateParam : dateParamList) {
            for (String day : dateList) {

                Long startTime = System.currentTimeMillis();
                //门店集市流水-新增供货商
                String url = "http://btyjt.c3.fxscm.net/cldpoint/getDsstorebill.do?ent=ENT7617&username="+tcConfig.getUsername()+"&password="+tcConfig.getPassword()+"&" + dateParam + "=" + day;

                String content = restTemplate.getForObject(url, String.class);

                Long respondTime = (System.currentTimeMillis() - startTime) / 1000;

                JSONObject jsonObjectResult = JSON.parseObject(content);
                JSONArray jsonArray = jsonObjectResult.getJSONArray("data");

                /**
                 * ShopCode    ShopName	ItemSmallClassName  ItemName
                 * 没有店名查询的的是所有的店,把获取到的数据取出来便利 然后挨个插入到表中
                 */
                JSONObject jsonObject;
                Integer allDataCount = jsonArray.size();
                List<DsstoreBill> thisDayData = Lists.newLinkedList();

                for (int i = 0; i < jsonArray.size(); i++) {
                    //把所有 ItemSmallClassName 为 酱料 的添加到list中
                    jsonObject = jsonArray.getJSONObject(i);
                    List<String> type = Lists.newLinkedList();

                    //进货量只算这两种类型
                    type.add("门店统配入库");
                    type.add("门店自采入库");

                    DsstoreBillBusType dsstoreBillBusType = new DsstoreBillBusType();
                    dsstoreBillBusType.setBillBusType(jsonObject.getOrDefault("BillBusType", "").toString());
                    dsstoreBillBusType.setBillType(jsonObject.getOrDefault("BillType", "").toString());
                    billTypeSet1.add(dsstoreBillBusType);


                    if (type.contains(jsonObject.getOrDefault("BillType", ""))
                            && !"山西配送中心".equals(jsonObject.getOrDefault("ShopName", "").toString())
                            && !"山东配送中心".equals(jsonObject.getOrDefault("ShopName", "").toString())) {

                        DsstoreBill dsstoreBill = convertToDsstoreBill(jsonObject);
                        DsstoreBillBusType dsstoreBillBusType2 = new DsstoreBillBusType();
                        dsstoreBillBusType2.setBillBusType(dsstoreBill.getBillBusType());
                        dsstoreBillBusType2.setBillType(dsstoreBill.getBillType());
                        billTypeSet2.add(dsstoreBillBusType2);

                        list.add(dsstoreBill);
                        thisDayData.add(dsstoreBill);

                        //计算入库金额
                        if (shopDayPurchaseMap.get(dsstoreBill.getShopCode()) != null) {

                        } else {
                            Map<String, DsstoreBill> thisDayPurchaseMap = new HashMap<>();
                            thisDayPurchaseMap.put(day, dsstoreBill);
                            shopDayPurchaseMap.put(dsstoreBill.getShopCode(), thisDayPurchaseMap);
                        }
                    }
                }
                logger.info("门店库存流水入库数据：{},数据时间：{},数据总数：{}，满足条件：{}条数据,请求响应时间：{}", dateParam, day, allDataCount, thisDayData.size(), respondTime);
                map.put(day + dateParam, thisDayData.size());
            }
        }


        //分批插入数据
        if (list.size() > 0) {
            for (DsstoreBill dsstoreBill : list) {
                try {
                    if (dtMap.get(dsstoreBill.getStoreBillDtid()) == null) {
                        //不存在增加
                        this.save(dsstoreBill);
                        dtMap.put(dsstoreBill.getStoreBillDtid(), dsstoreBill.getShopCode());
                    } else {
                        //存在就更新
                        this.updateById(dsstoreBill);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        }
        return map;

    }

    private DsstoreBill convertToDsstoreBill(JSONObject jsonObject) {
        DsstoreBill dsstoreBill = new DsstoreBill();
        dsstoreBill.setBillNo(jsonObject.getOrDefault("BillNO", "").toString());
        dsstoreBill.setOtherSideName(jsonObject.getOrDefault("OtherSideName", "").toString());
        dsstoreBill.setShopName(jsonObject.getOrDefault("ShopName", "").toString());
        dsstoreBill.setItemBigClassName(jsonObject.getOrDefault("ItemBigClassName", "").toString());
        dsstoreBill.setItemAssistNo(jsonObject.getOrDefault("ItemAssistNO", "").toString());
        dsstoreBill.setItemSpec(jsonObject.getOrDefault("ItemSpec", "").toString());
        dsstoreBill.setSellTaxes(convertToDecimal(jsonObject.getOrDefault("SellTaxes", "").toString()));
        dsstoreBill.setItemSmallClassCode(jsonObject.getOrDefault("ItemSmallClassCode", "").toString());
        dsstoreBill.setArriveMoney(convertToDecimal(jsonObject.getOrDefault("ArriveMoney", "").toString()));
        dsstoreBill.setStoreCode(jsonObject.getOrDefault("StoreCode", "").toString());
        dsstoreBill.setOutputRate(convertToDecimal(jsonObject.getOrDefault("outputRate", "").toString()));
        dsstoreBill.setStoreBillRemark(jsonObject.getOrDefault("StoreBillRemark", "").toString());
        dsstoreBill.setOutMainAmount(convertToDecimal(jsonObject.getOrDefault("OutMainAmount", "").toString()));
        dsstoreBill.setItemSign(jsonObject.getOrDefault("ItemSign", "").toString());
        dsstoreBill.setShopCode(jsonObject.getOrDefault("ShopCode", "").toString());
        dsstoreBill.setTaxMoney(convertToDecimal(jsonObject.getOrDefault("TaxMoney", "").toString()));
        dsstoreBill.setStoreBillDtid(jsonObject.getOrDefault("StoreBillDTID", "").toString());
        dsstoreBill.setModifyDate(convertToDate(jsonObject.getOrDefault("modifyDate", "").toString()));
        dsstoreBill.setStoreName(jsonObject.getOrDefault("StoreName", "").toString());
        dsstoreBill.setStoreBillidRemark(jsonObject.getOrDefault("StoreBillIDRemark", "").toString());
        dsstoreBill.setMainUnit(jsonObject.getOrDefault("MainUnit", "").toString());
        dsstoreBill.setGiftFlag(convertBooleanToInt(jsonObject.getOrDefault("GiftFlag", "").toString()));
        dsstoreBill.setOutStoreMoney(convertToDecimal(jsonObject.getOrDefault("OutStoreMoney", "").toString()));
        dsstoreBill.setItemId(jsonObject.getOrDefault("ItemID", "").toString());
        dsstoreBill.setItemSmallClassName(jsonObject.getOrDefault("ItemSmallClassName", "").toString());
        dsstoreBill.setStoreBillReState(convertBooleanToInt(jsonObject.getOrDefault("StoreBillReState", "").toString()));
        dsstoreBill.setBusUser(jsonObject.getOrDefault("BusUser", "").toString());
        dsstoreBill.setTaxes(convertToDecimal(jsonObject.getOrDefault("Taxes", "").toString()));
        dsstoreBill.setBatchCode(jsonObject.getOrDefault("BatchCode", "").toString());
        dsstoreBill.setInStoreMoney(convertToDecimal(jsonObject.getOrDefault("InStoreMoney", "").toString()));
        dsstoreBill.setIsOut(convertToInt(jsonObject.getOrDefault("isOut", "").toString()));
        dsstoreBill.setShopId(jsonObject.getOrDefault("ShopID", "").toString());
        dsstoreBill.setMakeTime(convertToDate(jsonObject.getOrDefault("MakeTime", "").toString()));
        dsstoreBill.setBillBusType(jsonObject.getOrDefault("BillBusType", "").toString());
        dsstoreBill.setProcessMoney(convertToDecimal(jsonObject.getOrDefault("processMoney", "").toString()));
        dsstoreBill.setItemCode(jsonObject.getOrDefault("ItemCode", "").toString());
        dsstoreBill.setPushOutStoreMoney(convertToDecimal(jsonObject.getOrDefault("PushOutStoreMoney", "").toString()));
        dsstoreBill.setInMainAmount(convertToDecimal(jsonObject.getOrDefault("InMainAmount", "").toString()));
        dsstoreBill.setPushOutStoreAmount(convertToDecimal(jsonObject.getOrDefault("PushOutStoreAmount", "").toString()));
        dsstoreBill.setStoreBillId(jsonObject.getOrDefault("StoreBillID", "").toString());
        dsstoreBill.setSellIncludeTaxMoney(convertToDecimal(jsonObject.getOrDefault("SellIncludeTaxMoney", "").toString()));
        dsstoreBill.setOutBusAmount(convertToDecimal(jsonObject.getOrDefault("OutBusAmount", "").toString()));
        dsstoreBill.setOtherSideType(jsonObject.getOrDefault("OtherSideType", "").toString());
        dsstoreBill.setPushInStoreMoney(convertToDecimal(jsonObject.getOrDefault("PushInStoreMoney", "").toString()));
        dsstoreBill.setYield(convertToDecimal(jsonObject.getOrDefault("yield", "").toString()));
        dsstoreBill.setArriveAmount(convertToDecimal(jsonObject.getOrDefault("ArriveAmount", "").toString()));
        dsstoreBill.setItemName(jsonObject.getOrDefault("ItemName", "").toString());
        dsstoreBill.setSysBatchCode(jsonObject.getOrDefault("SysBatchCode", "").toString());
        dsstoreBill.setCreateDate(convertToDate(jsonObject.getOrDefault("createDate", "").toString()));
        dsstoreBill.setAuditDate(convertToDate(jsonObject.getOrDefault("auditDate", "").toString()));
        dsstoreBill.setOtherSideId(jsonObject.getOrDefault("OtherSideID", "").toString());
        dsstoreBill.setBillType(jsonObject.getOrDefault("BillType", "").toString());
        dsstoreBill.setSellTaxMoney(convertToDecimal(jsonObject.getOrDefault("SellTaxMoney", "").toString()));
        dsstoreBill.setBillBusTypeId(jsonObject.getOrDefault("BillBusTypeId", "").toString());
        dsstoreBill.setPushInStoreAmount(convertToDecimal(jsonObject.getOrDefault("PushInStoreAmount", "").toString()));
        dsstoreBill.setInBusAmount(convertToDecimal(jsonObject.getOrDefault("InBusAmount", "").toString()));
        if (dsstoreBill.getStoreBillDtid().equals("2c910a61768f5d0f0176c193f3d34e46")) {
            System.out.println();
        }

        if (dsstoreBill.getStoreBillDtid().equals("2c910a61768f5d0f0176c193f3d34e46")) {
            System.out.println();
        }

        dsstoreBill.setBusDate(convertToDate(jsonObject.getOrDefault("busDate", "").toString()));
        dsstoreBill.setAPYear(convertToLong(jsonObject.getOrDefault("APYear", "").toString()));
        dsstoreBill.setItemBigClassCode(jsonObject.getOrDefault("ItemBigClassCode", "").toString());
        dsstoreBill.setSaleMoney(convertToDecimal(jsonObject.getOrDefault("SaleMoney", "").toString()));
        dsstoreBill.setStoreId(jsonObject.getOrDefault("StoreID", "").toString());
        dsstoreBill.setItemAbc(jsonObject.getOrDefault("ItemAbc", "").toString());
        dsstoreBill.setArrivalDate(convertToDate(jsonObject.getOrDefault("ArrivalDate", "").toString()));
        dsstoreBill.setAPMonth(convertToInt(jsonObject.getOrDefault("APMonth", "").toString()));
        dsstoreBill.setOtherSideCode(jsonObject.getOrDefault("OtherSideCode", "").toString());
        dsstoreBill.setBusUnit(jsonObject.getOrDefault("BusUnit", "").toString());
        dsstoreBill.setIncludeTaxMoney(convertToDecimal(jsonObject.getOrDefault("IncludeTaxMoney", "").toString()));
        dsstoreBill.setParentBillNo(jsonObject.getOrDefault("ParentBillNO", "").toString());
        return dsstoreBill;
    }


    /**
     * 递归-最多查3个月没有就拉倒，
     * 获取对应的最近的有门店期初单的日期
     *
     * @param dsstoreBill
     * @param busdateSets
     * @param paramMonthDay
     * @return
     */
    private String getRecentChuQiDanMonthDay(DsstoreBillResult dsstoreBill, Map<String, String> busdateSets, String paramMonthDay, int runTime) {
        //查询次数加1
        runTime = runTime + 1;
        //最多查3次，如果查不到错就错吧，本来3个月都没有初期单的话，不是新店，就是没月底盘点。新店没有正常，老店3个月没有的话，就有问题，待定。
        if (runTime > 3) {
            return "";
        }
        //获取查询参数中开始时间的上个月
        String lastMonthDay = null;
        try {
            lastMonthDay = DateUtil.lastMonthByDate(paramMonthDay);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        //001_101_1000004_2019-12-01，shopCode_item_small_class_code_item_code_bus_date,门店编码_品类_品项_业务日期
        String val = dsstoreBill.getShopCode() + '_' + dsstoreBill.getItemSmallClassCode() + '_' + dsstoreBill.getItemCode() + '_' + lastMonthDay;
        if (busdateSets.get(val) != null) {
            return (String) busdateSets.get(val);
        }
        //递归，继续执行此方法
        getRecentChuQiDanMonthDay(dsstoreBill, busdateSets, lastMonthDay, runTime);
        return "";
    }


    private Serializable getKey(DsstoreBillParam param) {
        return param.getStoreBillDtid();
    }

    private Page getPageContext() {
        return LayuiPageFactory.defaultPage();
    }

    private DsstoreBill getOldEntity(DsstoreBillParam param) {
        return this.getById(getKey(param));
    }

    private DsstoreBill getEntity(DsstoreBillParam param) {
        DsstoreBill entity = new DsstoreBill();
        ToolUtil.copyProperties(param, entity);
        return entity;
    }

    /**
     * 转换时间格式
     *
     * @param time 参数
     * @return 转换之后的时间格式
     */
    public static String convertTime(String time) {
        // May 31, 2020 1:43:39 PM
        Date date = new Date(time);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        time = simpleDateFormat.format(date);
        return time;
    }

    /**
     * 处理不合理数据，0E-8，0e-8
     */
    private String convertNum(String data) {
        if ("0E-8".equals(data) || "0-8".equals(data) || "0E-12".equals(data) || "0e-12".equals(data)) {
            return "0";
        } else {
            return data;
        }
    }


    /**
     * 转换数字为decimal
     *
     * @param data 参数
     * @return
     */
    public static BigDecimal convertToDecimal(String data) {
        if (StringUtils.isBlank(data) || "0E-8".equals(data) || "0-8".equals(data) || "0E-12".equals(data) || "0e-12".equals(data)) {
            return BigDecimal.ZERO;
        }
        BigDecimal decimal = new BigDecimal(data);
        return decimal;
    }

    public static Date convertToDate(String time) {
        if (StringUtils.isBlank(time)) {
            return null;
        }
        Date date1 = new Date(time);
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateStr = sdf1.format(date1);

        Date date = null;
        try {
            date = sdf1.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    public static Integer convertBooleanToInt(String flag) {
        if (flag.equals("false")) {
            return 0;
        } else if (flag.equals("true")) {
            return 1;
        }
        return null;
    }

    public static Integer convertToInt(String data) {
        if (StringUtils.isBlank(data) || "0E-8".equals(data) || "0-8".equals(data) || "0E-12".equals(data) || "0e-12".equals(data)) {
            return 0;
        }
        Integer integer = Integer.valueOf(data);
        return integer;
    }

    public static Long convertToLong(String data) {
        if (StringUtils.isBlank(data) || "0E-8".equals(data) || "0-8".equals(data) || "0E-12".equals(data) || "0e-12".equals(data)) {
            return 0L;
        }
        Long lon = Long.valueOf(data);
        return lon;
    }


    private String getItemCodes(DsstoreBillResult dsstoreBill) {

        return dsstoreBill.getShopCode() + "_" + dsstoreBill.getItemSmallClassCode() + "_" + dsstoreBill.getItemCode();
    }
}
